<?php
class SwfUploadComponent extends Object {

	var $settings = array(
						'maxSize'				=> '',
						'uploadPath' 			=> '/uploads/',						
						'uploadName'			=> 'Filedata',
						'fileName'  			=> '',
						'fileExtension'			=> '',
						'maxFileNameLength'  	=> 260,	
						'extensionWhitelist' 	=> array('zip'),											
						'characterWhitelist' 	=> '.A-Z0-9_ !@#$%^&()+={}\[\]\',~`-',						
					);

	function startup(&$controller){
	//take the min of post_max_size or upload_max_filesize
		$this->settings['maxSize'] = min($this->__convertToBytes(ini_get('post_max_size')), $this->__convertToBytes(ini_get('upload_max_filesize')));
	} // startup
	
	
	function upload() {
		if(!isset($_FILES)) :
			return false;
			trigger_error("You've gotta send files if you want to upload something. Although there could be something mysterious going on ...");
			exit();
		endif;
		if($this->settings['uploadPath'] == '/uploads/'){
			$this->settings['fileName'] = $_FILES[$this->settings['uploadName']]["name"];
			$this->settings['uploadPath'] =  WWW_ROOT.$this->settings['uploadPath'];			
		}

		if(!file_exists($this->settings['uploadPath'])){
			mkdir($this->settings['uploadPath']);
		}
		if(!$this->__validateUpload()){
			return false;
		}
		//if you've escaped from validation unscathed, move the file
		if (!@move_uploaded_file($_FILES[$this->settings['uploadName']]["tmp_name"], $this->settings['uploadPath'].$this->settings['fileName'])) {
			return false;
			trigger_error("File could not be saved, aka move_uploaded_file failed.");
		} else {
			return true;
		}		
	} // upload
	
	
	function __validateUpload() {
	// Validate the $_FILES array
		//if the "upload name" is different than what we are working with
		if(empty($_FILES)) {
			return false;
			trigger_error("Your $_FILES array is empty, this is indicative of a large file.");
			exit();
		} else if (!isset($_FILES[$this->settings['uploadName']])) {
			return false;
			trigger_error("Check your uploadName, it probably isn't ". $this->settings['uploadName']);
			exit();
		// if php has sent across an error with the file
		} else if (isset($_FILES[$this->settings['uploadName']]["error"]) && $_FILES[$this->settings['uploadName']]["error"] != 0) {
			return false;
			trigger_error($_FILES[$this->settings['uploadName']]["error"]);
			exit();
		// check is the file actually is an uploaded file and not something malicious
		} else if (!isset($_FILES[$this->settings['uploadName']]["tmp_name"]) || !@is_uploaded_file($_FILES[$this->settings['uploadName']]["tmp_name"])) {
			return false;
			trigger_error("Someone is maliciously uploading things maybe?");
			exit();		
		// make sure there is a file name
		} else if (!isset($_FILES[$this->settings['uploadName']]['name'])) {
			return false;
			trigger_error("The file had no name.");
			exit();
		}		
		
	// Validate the file size (Warning: the largest files supported by this code is 2GB)
		$size = @filesize($_FILES[$this->settings['uploadName']]["tmp_name"]);
		if (!$size || $size > $this->settings['maxSize']) {
			return false;
			trigger_error("File exceeds the maximum allowed size");
			exit();
		}
		if ($size <= 0) {
			return false;
			trigger_error("Why is this file smaller than zero?");
			exit();
		}
		
	// Validate file name (for our purposes we'll just remove invalid characters)
		$this->settings['fileName'] = preg_replace('/[^'.$this->settings['characterWhitelist'].']|\.+$/i', "", basename($this->settings['fileName']));
		if (strlen($this->settings['fileName']) == 0 || strlen($this->settings['fileName']) > $this->settings['maxFileNameLength']) {
			return false;
			trigger_error("Invalid file name");
			exit();
		}	
		// Validate that we won't over-write an existing file
		if (file_exists($this->settings['uploadPath'] . $this->settings['fileName'])) {
			return false;
			trigger_error("File with this name already exists");
			exit();
		}
		// Validate file extensione
		$path_info = pathinfo($_FILES[$this->settings['uploadName']]['name']);
		$fileExtension = $path_info["extension"];
		$isValid = false;
		foreach ($this->settings['extensionWhitelist'] as $extension) {
			if (strcasecmp($fileExtension, $extension) == 0) {
				return true;
				$isValid = true;
				break;
			}
		}
		if (!$isValid) {
			return false;
			trigger_error("Invalid file extension");
			exit();
		}				
	}
	
	function __getMaxPostSize() {
		$size = ini_get('post_max_size');
		return $size;
	} // __getMaxPostSize
	
	
	function __setMaxPostSize($size = false) {
		if(!$size) :
			$size = $this->settings['maxPostSize'];
		endif;
		
		if(!ini_set('post_max_size', $size)) :
			return false;
			trigger_error('Your ini is, like, totally unmodifiable.');
			return false;
		else :
			return true;
		endif;
	} // __setMaxPostSize
	
	
	function __convertToBytes($str) {
		$unit = strtoupper(substr($str, -1));
		if(!(($unit == 'M') || ($unit == 'K') || ($unit == 'G'))) :
			return false;
			trigger_error('Your max_post_size is not in the right format');
		endif;

		$multiplier = ($unit == 'M' ? 1048576 : ($unit == 'K' ? 1024 : ($unit == 'G' ? 1073741824 : 1)));
		$bits = $multiplier * (int)$str;
		
		return $bits;
	} // __convertToBytes
		
} // class
?>